#pragma once

#include <iostream>
#include <string>
#include <poll.h>
#include <memory>
#include "Log.hpp"
#include "Socket.hpp"

using namespace Net_Work;

const static int gdefaultport = 8888;
const static int gbacklog = 8;
const static int gnum = 1024;
const static int gdefaultfd = -1;
const static int gdefultevent = 0;

class PollServer
{
public:
    PollServer(int port = gdefaultport) : _port(port), _listensock(new TcpSocket()), _isrunning(false), _timeout(-1)
    {
    }
    void HandlerEvents()
    {
        for (int i = 0; i < gnum; i++)
        {
            if (_events[i].fd == gdefaultfd)
                continue;

            int fd = _events[i].fd;
            short revents = _events[i].revents;
            if (revents & POLLIN)
            {
                if (fd == _listensock->GetSockFd())
                {
                    // 新连接到来
                    std::string clientip;
                    uint16_t clientport;
                    int sockfd = _listensock->AcceptConnection(&clientip, &clientport);
                    if (sockfd < 0)
                        continue;
                    lg.LogMessage(Debug, "get a new client, %s:%d\n", clientip.c_str(), clientport);
                    int j = 0;
                    for (; j < gnum; j++)
                    {
                        if (_events[j].fd == gdefaultfd)
                            break;
                    }
                    if (j < gnum)
                    {
                        // 给poll添加新的sockfd
                        _events[j].fd = sockfd;
                        _events[j].events = POLLIN;
                        _events[j].revents = gdefultevent;
                        lg.LogMessage(Debug, "add a new client, fd is : %d\n", sockfd);
                        PrintDebug();
                    }
                    else
                    {
                        // 扩容或者close
                    }
                }
                else
                {
                    char buffer[1024];
                    // fd上面的读事件就绪了
                    ssize_t n = recv(fd, buffer, sizeof(buffer) - 1, 0);
                    if (n > 0)
                    {
                        buffer[n] = 0;
                        lg.LogMessage(Debug, "client info# %s\n", buffer);

                        std::string echo_message = "[server echo]# ";
                        echo_message += buffer;
                        // 写回去 --- epoll会说
                        send(fd, echo_message.c_str(), echo_message.size(), 0);
                    }
                    else if (n == 0)
                    {
                        ::close(fd);
                        _events[i].fd = gdefaultfd;
                        _events[i].events = _events[i].revents = gdefultevent;
                        lg.LogMessage(Info, "client quit..., remove fd: %d\n", fd);
                        PrintDebug();
                    }
                    else
                    {
                        ::close(fd);
                        _events[i].fd = gdefaultfd;
                        _events[i].events = _events[i].revents = gdefultevent;
                        lg.LogMessage(Info, "recv error..., remove fd: %d\n", fd);
                        PrintDebug();
                    }
                }
            }
            if (revents & POLLOUT)
            {
                // TODO
            }
        }
    }

     ~PollServer()
    {
    }
private:
    std::unique_ptr<Socket> _listensock;
    int _port;
    int _isrunning;
    struct pollfd _events[gnum];
    int _timeout;
};